﻿using System;
using System.Data;
using System.Xml.Serialization;
using EPiServer.Core;
using EPiServer.DataAccess;
using EPiServer.Editor;
using EPiServer.Security;
using EPiServer.Web.PropertyControls;

namespace TemplateFoundation.Tests.Environment
{
    [Serializable]
    public class PropertyLongString : PropertyData, IPropertyLoadDataHandler
    {
        // Fields
        private AutoCompressString _compressedLongString;
        private bool _delayedLoading;
        private EditorToolOption _editorToolOptions;
        private PropertyData _folder;
        private Guid _longStringGuid;
        [NonSerialized]
        private PropertyLongString _originalProperty;
        private PageReference _pageLink;

        // Methods
        public PropertyLongString()
        {
            this._longStringGuid = Guid.Empty;
        }

        public PropertyLongString(string value)
            : base(string.IsNullOrEmpty(value))
        {
            this._longStringGuid = Guid.Empty;
            this._compressedLongString = new AutoCompressString(value);
        }

        public override PropertyData Copy()
        {
            PropertyLongString str = (PropertyLongString)base.Copy();
            if (!this.IsLongStringLoaded)
            {
                if (this._originalProperty != null)
                {
                    str._originalProperty = this._originalProperty;
                    return str;
                }
                str._originalProperty = this;
            }
            return str;
        }

        public override IPropertyControl CreatePropertyControl()
        {
            return new PropertyLongStringControl();
        }

        void IPropertyLoadDataHandler.Load(string key, IDataRecord record)
        {
            base.ThrowIfReadOnly();
            this.ReadAdditionalDatabaseInformation(record);
            object obj2 = record[key];
            if (obj2 != DBNull.Value)
            {
                this.LoadData(obj2);
            }
        }

        protected internal string GetDelayedLoadedString(bool storeLocally)
        {
            string str2;
            if ((this._originalProperty != null) && this._originalProperty.IsLongStringLoaded)
            {
                this.SetDelayLoadedValue(this._originalProperty._compressedLongString);
                if (this._compressedLongString != null)
                {
                    return this._compressedLongString.ToString();
                }
                return null;
            }
            try
            {
                string str = new PageLoadDB().LoadLongString(this._longStringGuid);
                if (storeLocally)
                {
                    this.SetDelayLoadedValue(new AutoCompressString(str));
                }
                else
                {
                    this._delayedLoading = false;
                }
                if (this._originalProperty != null)
                {
                    this._originalProperty.SetDelayLoadedValue(this._compressedLongString);
                }
                str2 = str;
            }
            catch (InconsistentDataException exception)
            {
                exception.PageLink = this.PageLink;
                throw exception;
            }
            return str2;
        }

        public override void InitializeData(PropertyDataCollection properties)
        {
            base.ThrowIfReadOnly();
            this._pageLink = PageReference.EmptyReference;
            if (properties != null)
            {
                PropertyPageReference reference = properties["PageLink"] as PropertyPageReference;
                PropertyData data1 = properties["PageParentLink"];
                this._pageLink = (reference != null) ? reference.PageLink : PageReference.EmptyReference;
                this._folder = properties["PageFolderID"];
            }
        }

        public static PropertyLongString Parse(string value)
        {
            PropertyLongString str = new PropertyLongString();
            str.LongString = value;
            str.IsModified = false;
            return str;
        }

        public override PropertyData ParseToObject(string value)
        {
            return Parse(value);
        }

        public override void ParseToSelf(string value)
        {
            this.Value = Parse(value).Value;
        }

        protected void ReadAdditionalDatabaseInformation(IDataRecord record)
        {
            bool flag = record.GetType().FullName.Contains("Oracle");
            for (int i = record.FieldCount - 1; i >= 0; i--)
            {
                if (string.Compare(record.GetName(i), "Guid", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    if (!record.IsDBNull(i))
                    {
                        if (!flag)
                        {
                            this._longStringGuid = record.GetGuid(i);
                        }
                        else
                        {
                            this._longStringGuid = new Guid(record.GetString(i));
                        }
                        this._delayedLoading = true;
                        return;
                    }
                    break;
                }
            }
        }

        protected override void SetDefaultValue()
        {
            base.ThrowIfReadOnly();
            this._compressedLongString = AutoCompressString.Empty;
        }

        private void SetDelayLoadedValue(AutoCompressString stringValue)
        {
            this._compressedLongString = stringValue;
            this._delayedLoading = false;
        }

        public override string ToWebString()
        {
            if (this.EditorToolOptions == 0)
            {
                return base.ToWebString();
            }
            return base.ToString();
        }

        // Properties
        [Obsolete("Use EditorToolOptions instead.", false)]
        public virtual EditorToolOption EditorSettings
        {
            get
            {
                return this.EditorToolOptions;
            }
            set
            {
                this.EditorToolOptions = value;
            }
        }

        public virtual EditorToolOption EditorToolOptions
        {
            get
            {
                if (PrincipalInfo.Current.IsPermitted(Permission.EditorUnlimitedFunctions))
                {
                    return ~EditorToolOption.DynamicContent;
                }
                return this._editorToolOptions;
            }
            set
            {
                base.ThrowIfReadOnly();
                this._editorToolOptions = value & ~EditorToolOption.DynamicContent;
            }
        }

        public virtual int FolderID
        {
            get
            {
                if (this._folder != null)
                {
                    return (int)this._folder.Value;
                }
                return 0;
            }
        }

        public bool IsLongStringLoaded
        {
            get
            {
                return !this._delayedLoading;
            }
        }

        public override bool IsNull
        {
            get
            {
                return (base.IsNull && (this._longStringGuid == Guid.Empty));
            }
        }

        [XmlIgnore]
        protected virtual string LongString
        {
            get
            {
                if (!this.IsLongStringLoaded)
                {
                    return this.GetDelayedLoadedString(true);
                }
                if (this._compressedLongString != null)
                {
                    return this._compressedLongString.ToString();
                }
                return null;
            }
            set
            {
                base.ThrowIfReadOnly();
                this._delayedLoading = false;
                if (PropertyData.QualifyAsNullString(value))
                {
                    base.Clear();
                }
                else
                {
                    string str = (this._compressedLongString == null) ? null : this._compressedLongString.ToString();
                    if ((value != str) || this.IsNull)
                    {
                        this._compressedLongString = new AutoCompressString(value);
                        base.Modified();
                    }
                }
            }
        }

        public virtual PageReference PageLink
        {
            get
            {
                return this._pageLink;
            }
            set
            {
                base.ThrowIfReadOnly();
                this._pageLink = value;
            }
        }

        public override Type PropertyValueType
        {
            get
            {
                return typeof(string);
            }
        }

        public override PropertyDataType Type
        {
            get
            {
                return PropertyDataType.LongString;
            }
        }

        public override object Value
        {
            get
            {
                if (this.IsNull)
                {
                    return null;
                }
                return LongString;
            }
            set
            {
                base.SetPropertyValue(value, delegate
                {
                    LongString = value.ToString();
                });
            }
        }
    }
}